package com.wing.order.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wing.common.exception.BusinessException;
import com.wing.common.utils.CodeUtil;
import com.wing.common.utils.JsonResult;
import com.wing.common.utils.Result;
import com.wing.enterprise.device.response.DeviceVO;
import com.wing.enterprise.feign.EnterpriseClient;
import com.wing.enterprise.product.model.response.*;
import com.wing.order.dao.*;
import com.wing.order.model.entity.*;
import com.wing.order.model.request.InventoryInoutForm;
import com.wing.order.model.response.InventoryInoutVO;
import com.wing.order.model.response.InventoryJobLabelVO;
import com.wing.product.model.entity.Product;
import com.wing.product.model.entity.ProductPackLabel;
import com.wing.product.model.request.ProductPackLabelForm;
import com.wing.product.service.ProductDetailService;
import com.wing.product.service.ProductPackLabelService;
import com.wing.warehouse.dao.WarehouseDao;
import com.wing.warehouse.model.response.WarehouseVO;
import com.wing.web.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 入库单-ServiceImpl
 *
 * @author
 */
@Service
@Slf4j
public class InventoryInoutServiceImpl extends ServiceImpl<InventoryInoutDao, InventoryInout> implements InventoryInoutService {

    @Autowired
    InventoryInoutDao inventoryInoutDao;
    @Autowired
    private EnterpriseClient productDetailClient;
    @Autowired
    private DynamicDao dynamicDao;
    @Autowired
    private WarehouseDao warehouseDao;
    @Autowired
    private ProductDetailService productDetailService;
    @Autowired
    private com.wing.product.dao.ProductDao ProductDao;
    @Autowired
    private com.wing.product.dao.ProductTypeDao productTypeDao;
    @Autowired
    private com.wing.product.dao.ProductUnitDao ProductUnitDao;
    @Autowired
    private OrderDeliverySignDao orderDeliverySignDao;
    @Autowired
    private InventoryJobSignProductDao signProductDao;

    @Autowired
    private InventoryJobSignProductDetailDao SignProductDetailDao;
    @Autowired
    private OrderDeliverySignDetailDao  signDetailDao;
    @Autowired
    private InventoryJobLabelDao jobLabelDao;
    @Autowired
    private InventoryJobProductDao  inventoryJobProductDao;
    @Autowired
    private InventoryJobLabelDao inventoryJobLabelDao;
    @Autowired
    private EnterpriseClient enterpriseClient;
    @Autowired
    private InventoryInoutDetailDao inventoryInoutDetailDao;
    @Autowired
    private InventoryInoutDetailService inventoryInoutDetailService;
    @Autowired
    private ProductPackLabelService productPackLabelService;


    @Override
    @Transactional
    public void add(InventoryInoutForm inventoryInoutForm) {
        String loginUsername = JwtUtils.getLoginUsername();
        inventoryInoutForm.setCreatorName(loginUsername);
        String skuCode = inventoryInoutForm.getSkuCode();
        //将入库计划的产品存入
        InventoryInoutDetail inventoryInoutDetail = new InventoryInoutDetail();
        com.wing.product.model.response.ProductDetailVO detailVO = productDetailService.getProductInfoBySkuCode(skuCode);
        //如果入库类型是签收刀具入库 查询cab库
        inventoryInoutForm.setSkuCode(detailVO.getSkuCode());
        inventoryInoutForm.setSpecCode(detailVO.getSkuSpecValueNames());
        inventoryInoutForm.setProductTypeId(detailVO.getProductTypeId());
        inventoryInoutForm.setProductType(detailVO.getProductTypeName());
        inventoryInoutDetail.setSkuCode(skuCode);
        inventoryInoutDetail.setSkuPic(detailVO.getProductPic());
        inventoryInoutDetail.setProductName(detailVO.getSkuName());
        inventoryInoutDetail.setSkuSpecCode(detailVO.getSkuSpecValueNames());
        inventoryInoutDetail.setMarketPrice(detailVO.getMarketPrice());
        inventoryInoutDetail.setProductCode(detailVO.getProductCode());
        inventoryInoutDetail.setProductTypeId(detailVO.getProductTypeId());
        inventoryInoutDetail.setProductType(detailVO.getProductTypeName());
        //单位
        com.wing.product.model.response.ProductUnitVO productUnitVO = ProductUnitDao.get4appById(inventoryInoutForm.getUnitId());
        inventoryInoutForm.setUnitId(productUnitVO.getId());
        inventoryInoutForm.setUnitName(productUnitVO.getName());
        inventoryInoutDetail.setUnitId(productUnitVO.getId());
        inventoryInoutDetail.setUnitName(productUnitVO.getName());

        //包装方案
        JsonResult<ProductPackVO> packJson = productDetailClient.getProductPackById(inventoryInoutForm.getPageSchemeId());
        inventoryInoutForm.setPageScheme(packJson.getData().getName());
        inventoryInoutForm.setPageSchemeId(packJson.getData().getId());
        //仓库
        WarehouseVO warehouseVO = warehouseDao.get4appById(inventoryInoutForm.getWarehouseId());
        inventoryInoutForm.setWarehouseName(warehouseVO.getName());
        //台机工位
        JsonResult<DeviceVO> deviceJson = productDetailClient.getDeviceById(inventoryInoutForm.getProductionMachineId());
        inventoryInoutForm.setProductionMachineId(inventoryInoutForm.getProductionMachineId());
        inventoryInoutForm.setProductionMachine(deviceJson.getData().getDeviceCode());
        //入库计划单编号
        String code = "";
        String typeCode = "";
        InventoryInout.StorageType storageType = inventoryInoutForm.getStorageType();
        if(inventoryInoutForm.getInoutTypeCode().equals("production")){//生产
            typeCode = "SCR";
        }else if(inventoryInoutForm.getInoutTypeCode().equals("purchase")){//采购
            typeCode = "CGR";
        }else if(inventoryInoutForm.getInoutTypeCode().equals("allot")){//调拨
            typeCode = "DBR";
        }else if(inventoryInoutForm.getInoutTypeCode().equals("check")){//盘点
            typeCode = "PDR";
        }else if(inventoryInoutForm.getInoutTypeCode().equals("barter")){//换货
            typeCode = "HHR";
        }else if(inventoryInoutForm.getInoutTypeCode().equals("breakage")){//报损
            typeCode = "BSR";
        }else if(inventoryInoutForm.getInoutTypeCode().equals("cutter")){//刀具签收
            typeCode = "DJR";
        }
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date();
        String today = format.format(date);
        Integer maxCode = dynamicDao.getDayMaxNo("ord_inventory_inout");
        String maxNo = CodeUtil.getCode(maxCode);
        code = typeCode + today + maxNo;
        inventoryInoutForm.setCode(code);
        inventoryInoutForm.setNo(Integer.valueOf(maxNo));
        inventoryInoutForm.setDay(Integer.valueOf(today));
        inventoryInoutForm.setStatus(InventoryInout.Status.stockup);
        //校验
        InventoryInout inventoryInout =new InventoryInout();
        CopyOptions copyOptions = CopyOptions.create()
        .setEditable(InventoryInout.class)
        .setIgnoreError(true)
        .setIgnoreNullValue(true);
        BeanUtil.copyProperties(inventoryInoutForm, inventoryInout, copyOptions);
        baseMapper.insert(inventoryInout);
        //入库计划的产品
        inventoryInoutDetail.setPlanId(inventoryInout.getId());
        inventoryInoutDetailDao.insert(inventoryInoutDetail);
        //添加包装条码
        Integer snNum = inventoryInoutForm.getSnNum();
            ProductPackLabelForm productPackLabelForm = new ProductPackLabelForm();
            productPackLabelForm.setWorkOrderCode(inventoryInoutForm.getProductionPlanCode());
            productPackLabelForm.setSkuCode(inventoryInoutForm.getSkuCode());
            productPackLabelForm.setProductionManager(inventoryInoutForm.getManufactureHeadName());
            productPackLabelForm.setProductUnitId(inventoryInoutForm.getUnitId());
            productPackLabelForm.setPackId(inventoryInoutForm.getPageSchemeId());
            productPackLabelForm.setBatchCode(code);
            productPackLabelForm.setFeeder(inventoryInoutForm.getFeedingPeople());
            productPackLabelForm.setWarehouseId(inventoryInoutForm.getWarehouseId());
            productPackLabelForm.setRemark(inventoryInoutForm.getRemark());
            productPackLabelForm.setAddCount(snNum);
            productPackLabelForm.setQuantity(packJson.getData().getBaseRate());
            productPackLabelForm.setSurplusQuantity(packJson.getData().getBaseRate());
            productPackLabelForm.setFeedQuantity(inventoryInoutForm.getFeedQuantity().intValue());
            productPackLabelForm.setInoutTypeCode(inventoryInoutForm.getInoutTypeCode());
            productPackLabelForm.setInoutTypeName(inventoryInoutForm.getInoutTypeName());
            //productPackLabelForm.setInventoryTypeId(ProductPackLabel.InventoryTypeId.valueOf(inventoryInoutForm.getStorageType().toString()));
            productPackLabelForm.setRateType(ProductPackLabel.RateType.fixed);
            productPackLabelForm.setStatus(ProductPackLabel.Status.created);
            productPackLabelForm.setCreator(JwtUtils.getLoginUserId());
            productPackLabelForm.setCreatorName(JwtUtils.getLoginUsername());
            productPackLabelForm.setPlanId(inventoryInout.getId());
            //生产条码接口
             productPackLabelService.inertPackIndex2(productPackLabelForm);
    }

    @Override
    public List<InventoryInoutVO> list4app(Map<String, Object> params) {
        return baseMapper.list4app(params);
    }

    @Override
    public Page<InventoryInoutVO> pageList4app(Page page, Map<String, Object> params) {
        List<InventoryInoutVO> list = baseMapper.list4app(page, params);
        page.setRecords(list);
        return page;
    }

    @Override
    public InventoryInoutVO get4appById(Long id) {
        return baseMapper.get4appById(id);
    }

    @Override
    public IPage<InventoryInout> getInventoryInoutPageList(InventoryInout inventoryInout, Integer page, Integer limit) {
        IPage<InventoryInout> iPage = new Page<InventoryInout>(page, limit);
        QueryWrapper<InventoryInout> wrapper = new QueryWrapper<>();
        if(inventoryInout.getWarehouseId() != null){
            wrapper.eq("t1.warehouse_id", inventoryInout.getWarehouseId());
        }
        wrapper.eq(StringUtils.isNotBlank(inventoryInout.getInoutTypeCode()),"t1.inout_type_code", inventoryInout.getInoutTypeCode());
        if(inventoryInout.getProductTypeId() != null){
            wrapper.eq("t1.product_type_id", inventoryInout.getProductTypeId());
        }
        if(StringUtils.isNotEmpty(inventoryInout.getCode())){
            wrapper.and(qw -> qw.like("t1.code",inventoryInout.getCode()));
        }
        if(StringUtils.isNotEmpty(inventoryInout.getSkuCode())){
            wrapper.and(qw -> qw.like("t1.sku_code",inventoryInout.getSkuCode()));
        }
        if (inventoryInout.getStatus() != null) {
            wrapper.eq("t1.status", InventoryInout.Status.valueOf(inventoryInout.getStatus().toString()));
        }
        wrapper.orderByDesc("t1.create_time");
        inventoryInoutDao.getInventoryInoutPageList(iPage,wrapper);
        return iPage;
    }

    @Override
    public IPage<InventoryInoutVO> getInventoryAllPageList(Integer page, Integer limit, String code) {
        IPage<InventoryInoutVO> iPage = new Page<InventoryInoutVO>(page, limit);
        QueryWrapper<InventoryInoutVO> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(code),"i.code",code);
        wrapper.orderByDesc("i.create_time");
        inventoryInoutDao.getInventoryAllPageList(iPage,wrapper);
        return iPage;
    }

    @Transactional
    @Override
    public void packLabelSign(List<ProductPackLabelVO> signList) {
        if(CollectionUtils.isEmpty(signList)){
            throw new BusinessException("签收参数异常");
        }
        InventoryInoutVO inoutVO = inventoryInoutDao.get4appById(signList.get(0).getPlanId());
        if(inoutVO == null){
            throw new BusinessException("当前签收的计划不存在");
        }
        ArrayList<String> skuCodeList = new ArrayList<>();
        //签收记录
        OrderDeliverySign orderDeliverySign = new OrderDeliverySign();
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date();
        String today = format.format(date);
        Integer maxCode = dynamicDao.getDayMaxNo("ord_order_delivery_sign");
        String maxNo = CodeUtil.getCode(maxCode);
        orderDeliverySign.setCode("SCQS" + today + maxNo);
        orderDeliverySign.setNo(Integer.valueOf(maxNo));
        orderDeliverySign.setDay(Integer.valueOf(today));
        orderDeliverySign.setPlanId(inoutVO.getId());
        orderDeliverySign.setSignType(OrderDeliverySign.SignType.storage);
        orderDeliverySign.setCreatorName(JwtUtils.getLoginUsername());
        orderDeliverySignDao.insert(orderDeliverySign);
        //签收产品主表
        InventoryJobSignProduct signProduct = new InventoryJobSignProduct();
        signProduct.setSignId(orderDeliverySign.getId())
                   .setPlanId(inoutVO.getId());
        signProductDao.insert(signProduct);
        //签收的产品详情，包装条码操作
        Long signProductDetailId = null;
        for (ProductPackLabelVO item : signList){
            boolean falg = skuCodeList.stream().filter(m -> m.equals(item.getSkuCode())).findAny().isPresent();
            if(!falg){
                InventoryInoutDetail inoutDetail = inventoryInoutDetailService.getInventoryInoutDetail(inoutVO.getId(), item.getSkuCode());
                //签收产品详情
                InventoryJobSignProductDetail signProductDetail = new InventoryJobSignProductDetail();
                signProductDetail.setSignId(orderDeliverySign.getId())
                        .setPlanId(inoutVO.getId())
                        .setSignProductId(signProduct.getId())
                        .setSkuCode(item.getSkuCode())
                        .setProductName(inoutDetail.getProductName())
                        .setUnitId(inoutDetail.getUnitId())
                        .setProductType(inoutDetail.getProductType())
                        .setProductCode(inoutDetail.getProductCode())
                        .setUnitName(inoutDetail.getUnitName());
                SignProductDetailDao.insert(signProductDetail);
                signProductDetailId = signProductDetail.getId();
                skuCodeList.add(item.getSkuCode());
            }

            //签收记录详情
            /*OrderDeliverySignDetail orderDeliverySignDetail = new OrderDeliverySignDetail();
            orderDeliverySignDetail.setSignId(orderDeliverySign.getId())
                    .setSkuCode(item.getSkuCode())
                    .setQuantity(item.getPackLabeQuantity().intValue());
            signDetailDao.insert(orderDeliverySignDetail);*/

            //查询出入库计划的产品
            QueryWrapper<InventoryInoutDetail> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("sku_code", item.getSkuCode());
            queryWrapper.eq("plan_id",signList.get(0).getPlanId());
            InventoryInoutDetail jobProduct = inventoryInoutDetailDao.selectOne(queryWrapper);
            //签收的包装条码
            InventoryJobLabel jobLabel = new InventoryJobLabel();
            jobLabel.setPlanId(inoutVO.getId())
                    .setSignId(orderDeliverySign.getId())
                    .setPlanId(inoutVO.getId())
                    .setPackLabeQuantity(item.getPackLabeQuantity())
                    .setAbnormalQuantity(item.getAbnormalQuantity())
                    .setQuantity(item.getQuantity().longValue())
                    .setStatus(InventoryJobLabel.Status.sign)
                    .setInoutType(InventoryJobLabel.InoutType.in)
                    .setPackLabeId(item.getId())
                    .setPackLabeCode(item.getCode())
                    .setPackId(item.getPackId())
                    .setSignProductDetailId(signProductDetailId)
                    .setWarehouseId(inoutVO.getWarehouseId())
                    .setPackName(item.getPackName());
            jobLabelDao.insert(jobLabel);
            //将包装条码的状态改为签收
            com.wing.product.model.response.ProductPackLabelVO packLabelVO = productPackLabelService.get4appById(item.getId());
            packLabelVO.setStatus(ProductPackLabel.Status.signed);
            ProductPackLabel productPackLabel = new ProductPackLabel();
            CopyOptions copyOptions = CopyOptions.create()
                    .setEditable(ProductPackLabel.class)
                    .setIgnoreError(true)
                    .setIgnoreNullValue(true);
            BeanUtil.copyProperties(packLabelVO, productPackLabel, copyOptions);
            productPackLabelService.updateById(productPackLabel);
           /* JsonResult jsonResult = enterpriseClient.updateProductPackLabel(labelVOJsonResult.getData());
            if (jsonResult.getCode() != Result.Code.SUCCESS.getCode()) {
                throw new BusinessException("修改包装条码状态异常");
            }*/

        }
    }

    @Override
    public List<InventoryJobLabelVO> getInventorySignProduct(Long planId) {
        return inventoryJobLabelDao.getInventorySignProduct(planId);
    }

    @Override
    public List<InventoryJobLabelVO> getInventorySignPackLabel(Long jobProductId) {
        return inventoryJobLabelDao.getInventorySignPackLabel(jobProductId);
    }

    @Override
    public List<InventoryInout> getStoragePlanAll() {
        QueryWrapper<InventoryInout> wrapper = new QueryWrapper<>();
        wrapper.select("id","code");
        List<InventoryInout> list = inventoryInoutDao.selectList(wrapper);
        return list;
    }

    @Override
    public InventoryInoutVO getInventoryInoutVOInfo(Long planId) {
        return inventoryInoutDao.getInventoryInoutVOInfo(planId);
    }

    @Override
    public Map findProduct(String skuCode) {
        return baseMapper.findProduct(skuCode);
    }

    @Override
    public List<Long> findWarehouseId(String skuCode) {
        return baseMapper.findWarehouseId(skuCode);
    }

    @Override
    public List<Map> findWarehouseInforById(Long id,String skuCode) {
        return baseMapper.findWarehouseInforById(id,skuCode);
    }

    @Override
    public Long queryProductStockNum(String skuCode) {
        return baseMapper.queryProductStockNum(skuCode);
    }

    @Override
    public List<Map> queryProductBoxList(String skuCode, Long id) {
        return baseMapper.queryProductBoxList(skuCode,id);
    }

    @Override
    public IPage<com.wing.product.model.response.ProductDetailVO> getInventoryProductDetailPageList(Integer page, Integer limit) {
        IPage<com.wing.product.model.response.ProductDetailVO> iPage = new Page<com.wing.product.model.response.ProductDetailVO>(page,limit);
        baseMapper.getInventoryProductDetailPageList(iPage);
        return iPage;
    }

    @Override
    public IPage<com.wing.product.model.response.ProductDetailVO> getProductList(Page<com.wing.product.model.response.ProductDetailVO> pg, Map params) {
        List<com.wing.product.model.response.ProductDetailVO> list = baseMapper.getProductList(pg, params);
        pg.setRecords(list);
        return pg;
    }

}
